import BaseMod from "../core/mvc/BaseMod"
import { GameEvent } from "../../common/game/event/GameEvent"
import App from "../App"
import { Protocol } from "../../common/protocol/Protocol"
import { Util } from "../../common/game/util/Util"
import { ClientEvent } from "../event/ClinetEvent"

const util = Util
const get = GameEvent.Type
const cet = ClientEvent.Type

/** 食物 */
export interface IFood {
    /** 唯一标识 */
    id: number,
    x: number,
    y: number,
    w: number,
    /** 颜色 */
    color?: string
}

/** 食物数据 */
export default class FoodMod extends BaseMod {


    private static _ins: FoodMod
    static get ins() { return FoodMod._ins || (FoodMod._ins = new FoodMod()) }

    private _screenFoodSet: Set<number>
    private _loadFoodMap = new Map<number, IFood>()
    private _unloadFoodMap = new Map<number, number>()

    /** 提取加载食物映射 */
    extractLoadFoods() {
        let extract = Array.from(this._loadFoodMap.values())
        this._loadFoodMap.clear()
        return extract
    }

    /** 提取卸载食物映射 <被吃食物id,吃食物的蛇节点id>*/
    extractUnloadFoodMap() {
        let extract = this._unloadFoodMap
        this._unloadFoodMap = new Map()
        return extract
    }


    protected initLocal(): void {
        this._screenFoodSet = new Set()

        this.gd.on(get.GAME_UPDATE, this, () => {
            let player = App.localPlayer

            //更新可见食物，获取待加载的和待卸载的食物
            let { loadFoods, unloadFoodMap } = player.updateScreenFoodMap(this._screenFoodSet)

            loadFoods.forEach(food => {
                this._loadFoodMap.set(food.id, food)
                this._unloadFoodMap.delete(food.id)
            })

            unloadFoodMap.forEach((eaterId, foodId) => {
                this._unloadFoodMap.set(foodId, eaterId)
                this._loadFoodMap.delete(foodId)
            })

            //发送事件通知view更新
            this._loadFoodMap.size && this.ed.send(cet.FOOD_LOAD, { model: this })
            this._unloadFoodMap.size && this.ed.send(cet.FOOD_UNLOAD, { model: this })
        })
    }


    protected initRemote(): void {

        //食物加载
        this.pd.on(Protocol.S2C_FOOD_LOAD, this, data => {

            let { loadFoods } = data

            loadFoods.forEach(food => {
                this._loadFoodMap.set(food.id, {
                    id: food.id,
                    x: food.x / 100,
                    y: food.y / 100,
                    w: food.w / 100,
                    color: food.rgb ? util.rgb2color(food.rgb + 1) : undefined
                })
                this._unloadFoodMap.delete(food.id)
            })

            //发送事件通知view更新
            this._loadFoodMap.size && this.ed.send(cet.FOOD_LOAD, { model: this })
        })

        //食物卸载
        this.pd.on(Protocol.S2C_FOOD_UNLOAD, this, data => {

            let { unloadFoods } = data

            unloadFoods.forEach(food => {
                this._unloadFoodMap.set(food.id, food.eaterId)
                this._loadFoodMap.delete(food.id)
            })

            //发送事件通知view更新
            this._unloadFoodMap.size && this.ed.send(cet.FOOD_UNLOAD, { model: this })
        })
    }

}